package br.srv.full.virtual.entities.auth;

import java.io.Serializable;
import java.util.Date;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

import br.srv.full.virtual.bean.base.QueryID;
import br.srv.full.virtual.entities.log.SiteUseControl;

@Entity
@Table(name = "userlogins")
@NamedQueries( { @NamedQuery(name = "Login.FindByLogin", query = "select ul from Login ul where  ul.loginName = ?1") })
public class Login implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = -7891498606967147596L;

	public static QueryID FIND_BY_LOGIN = new QueryID(Login.class, "Login.FindByLogin");

	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	@Column(name = "loginid")
	private Integer id;

	@Column(name = "userlogin", unique = true)
	private String loginName;

	@Column(name = "passwd")
	private String password;

	@Column(name = "validate")
	private Date validate;

	@Column(name = "createdate")
	@Temporal(TemporalType.TIMESTAMP)
	private Date createDate = new Date();

	/**
	 * Roles é uma propriedade que é usada constantemente no sistema, e pode
	 * sofrer altrações conforme a administração do usuário. devido a isto é
	 * indicado que seja sempre atualizada antes de ser usada. mas para
	 * performance ela será mantida junto do Login já em sua restauração.
	 * 
	 */
	@OneToMany(fetch = FetchType.EAGER, targetEntity = Role.class, cascade = { CascadeType.MERGE, CascadeType.REFRESH })
	@JoinTable(name = "loginroles", joinColumns = @JoinColumn(table = "userlogins", name = "loginid", referencedColumnName = "loginid", updatable = false, insertable = false), inverseJoinColumns = @JoinColumn(table = "roles", name = "rolename", referencedColumnName = "rolename"))
	private List<Role> roles;

	@ManyToOne(fetch = FetchType.EAGER, optional = false, targetEntity = br.srv.full.virtual.entities.auth.User.class, cascade = {
			CascadeType.MERGE, CascadeType.REFRESH })
	@JoinColumn(name = "userid", referencedColumnName = "userid", insertable = true, updatable = false)
	private User user;

	@OneToMany(fetch = FetchType.LAZY, mappedBy = "login", targetEntity = SiteUseControl.class)
	private List<SiteUseControl> siteUseControl;

	private Integer accessCount;

	/**
	 * @param p_user
	 */
	public Login(User p_user) {
		setUser(p_user);
	}

	/**
	 * 
	 */
	public Login() {
		// TODO Auto-generated constructor stub
	}

	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getLoginName() {
		return loginName;
	}

	public void setLoginName(String login) {
		this.loginName = login;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public Date getValidate() {
		return validate;
	}

	public void setValidate(Date validate) {
		this.validate = validate;
	}

	public List<Role> getRoles() {
		return roles;
	}

	public void setRoles(List<Role> p_roles) {
		this.roles = p_roles;
	}

	public Date getCreateDate() {
		return createDate;
	}

	public void setCreateDate(Date createDate) {
		this.createDate = createDate;
	}

	/**
	 * @return the siteUseControl
	 */
	public List<SiteUseControl> getSiteUseControl() {
		return siteUseControl;
	}

	/**
	 * @param p_siteUseControl
	 *            the siteUseControl to set
	 */
	public void setSiteUseControl(List<SiteUseControl> p_siteUseControl) {
		siteUseControl = p_siteUseControl;
	}

	/**
	 * @return the accessCount
	 */
	public Integer getAccessCount() {
		return accessCount;
	}

	/**
	 * @param p_acessCount
	 *            the accessCount to set
	 */
	public void setAccessCount(Integer p_acessCount) {
		accessCount = p_acessCount;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return getUser() + ", Login: " + getLoginName();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object p_obj) {
		boolean l_equals = p_obj != null;
		l_equals &= p_obj instanceof Login;
		if (l_equals) {
			Login l_login = (Login) p_obj;

			String l_loginName = getLoginName();
			String l_loginName2 = l_login.getLoginName();
			l_equals &= l_loginName != null;
			l_equals &= l_loginName2 != null;
			if (l_equals)
				l_equals &= l_loginName.equals(l_loginName2);
			else {
				// se um deles for nulo, irá entrar neste bloco
				// entáo verifica se ambos sáo nulos
				l_equals = l_loginName == null;
				l_equals &= l_loginName2 == null;
			}
		}
		return l_equals;
	}
}
